
const FairyGUI = CS.FairyGUI;
const FairyEditor = CS.FairyEditor
import UIWind, { WindData } from "./UIWind"
import ToolMgr from '../ToolMgr';
import SG, { Config, CustomCotrollerData } from '../SG';

export default class ControllerEditDialog extends UIWind {

    constructor() {
        super(new WindData("Extend", "ControllerEditDialog"))
    }

    static show() {
        let url = ToolMgr.joinUrl("Extend", "ControllerEditDialog")
        if (UIWind.FindUrl(url) == undefined) {
            UIWind.add(new this)
        }

        super.show(url)
    }

    private save: CS.FairyGUI.GButton;
    private cancel: CS.FairyGUI.GButton;

    private addPage: CS.FairyGUI.GButton;
    private removePage: CS.FairyGUI.GButton;
    private moveUp: CS.FairyGUI.GButton;
    private moveDown: CS.FairyGUI.GButton;
    private insertPage: CS.FairyGUI.GButton;

    private pageList: CS.FairyGUI.GList;

    private c_name: CS.FairyGUI.GComboBox;
    private name_input: CS.FairyGUI.GTextInput;
    private alias: CS.FairyGUI.GLabel;

    private addController: CS.FairyGUI.GButton;
    private delController: CS.FairyGUI.GButton;


    private datas: Record<string, CustomCotrollerData> = {}

    private keys = new Array<string>();

    protected onInit(): void {
        super.onInit();

        this.addController = this.contentPane.GetChild("addController").asButton;
        this.delController = this.contentPane.GetChild("delController").asButton;
        this.c_name = this.contentPane.GetChild("name").asComboBox;
        this.alias = this.contentPane.GetChild("alias").asLabel;

        this.save = this.contentPane.GetChild("save").asButton;
        this.cancel = this.contentPane.GetChild("cancel").asButton;

        this.addPage = this.contentPane.GetChild("addPage").asButton;
        this.removePage = this.contentPane.GetChild("removePage").asButton;
        this.moveUp = this.contentPane.GetChild("moveUp").asButton;
        this.moveDown = this.contentPane.GetChild("moveDown").asButton;
        this.insertPage = this.contentPane.GetChild("insertPage").asButton;

        this.save.onClick.Add(this.onSaveClick.bind(this));
        this.cancel.onClick.Add(this.onCancelClick.bind(this));

        this.addPage.onClick.Add(this.onAddPageClick.bind(this));
        this.removePage.onClick.Add(this.onRemovePageClick.bind(this));
        this.moveUp.onClick.Add(this.onMoveUpClick.bind(this));
        this.moveDown.onClick.Add(this.onMoveDownClick.bind(this));
        this.insertPage.onClick.Add(this.onInsertPageClick.bind(this));

        this.pageList = this.contentPane.GetChild("pageList").asList;
        this.pageList.itemRenderer = this.onItemRenerer.bind(this);

        this.name_input =  this.c_name.GetChild("title").asCom.GetChild("title").asTextInput;
        this.name_input.onFocusOut.Add(this.onNameChanged.bind(this));

        this.c_name.onChanged.Add(this.comboxChanged.bind(this));
        this.alias.GetChild("title").asTextInput.onFocusOut.Add(this.onAliasChanged.bind(this))

        this.addController.onClick.Add(this.onAddControllerClick.bind(this));
        this.delController.onClick.Add(this.onDelControllerClick.bind(this));
    }

    protected onShown(): void {
        super.onShown();

        this.keys = Object.keys(SG.config[Config.CUSTOMCONTROLLERNAME] as Record<string, CustomCotrollerData>);
        if (this.keys.length == 0) {
            this.initConfig();
        } else {
            this.datas = (JSON.parse(JSON.stringify(SG.config[Config.CUSTOMCONTROLLERNAME])) as Record<string, CustomCotrollerData>);
        }
        this.updateCombox(this.keys[0])
        this.comboxChanged();
    }

    protected onHide(): void {
        super.onHide();
        this.pageList.data = null;
        this.pageList.numItems = 0;
    }

    /**初始化配置 */
    private initConfig() {
        let config = this.datas;
        config['button'] = {
            name: 'button',
            remark: "",
            values: ["up", 'down', 'over', 'selectedOver'],
            values_remark: [],
        }
        config['grayed'] = this.creatorControllerData('grayed');
        config['checked'] = this.creatorControllerData('checked');
        config['expanded'] = this.creatorControllerData('expanded');
        config['lear'] = this.creatorControllerData('lear');

        this.keys = Object.keys(config);
    }

    //box改变刷新
    private comboxChanged() {
        let data = this.getCurrentConfigData();
        this.alias.text = data.remark;
        this.updatePageList();
    }

    /**控制器名称修改 */
    private onNameChanged() {
        let value = this.c_name.values.get_Item(this.c_name.selectedIndex);
        let data = this.datas[value];
        data.name = this.name_input.text;
        delete this.datas[value];
        this.datas[data.name] = data;
        this.keys[this.keys.indexOf(value)] = data.name;
        setTimeout(()=>{
            this.updateCombox(data.name);
        },0)
    }

    /**控制器备注名修改 */
    private onAliasChanged() {
        let data = this.getCurrentConfigData();
        data.remark = this.alias.GetTextField().text;
    }

    private onItemRenerer(index: number, obj: CS.FairyGUI.GComponent) {
        let name = obj.GetChild("name").asLabel;
        let remark = obj.GetChild("remark").asLabel;

        let data_name = this.pageList.data[0][index];
        let data_remark = this.pageList.data[1][index];

        name.text = data_name;
        remark.text = data_remark;

        let input_name = name.GetChild("input").asTextInput;
        let input_remark = remark.GetChild("input").asTextInput;

        input_name.text = data_name;
        input_remark.text = data_remark;

        obj.GetChild("index").text = index.toString();

        input_name.RemoveEventListeners();
        input_remark.RemoveEventListeners();

        input_name.onFocusOut.Add(this.inputNameChanged.bind(this, input_name, index))
        input_remark.onFocusOut.Add(this.inputRemarkChanged.bind(this, input_remark, index))
    }

    /**获取当前选择的控制器配置 */
    private getCurrentConfigData() {
        let key = this.c_name.value;
        return this.datas[key];
    }

    /**创建一个空的控制器 */
    private creatorControllerData(name: string) {
        return {
            name: name,
            remark: "",
            values: ["", ""],
            values_remark: ["", ""],
        }
    }

    //刷新下拉列表
    private updateCombox(key: string) {
        if (this.keys.length == 0) {
            this.initConfig();
            key = this.keys[0];

        }
        let list = ToolMgr.createGenericList<string>(CS.System.String);
        for (let index = 0; index < this.keys.length; index++) {
            list.Add(this.keys[index])
        }
        this.c_name.items = list.ToArray();
        this.c_name.values = list.ToArray();
        this.c_name.value = key;
    }

    /**刷新列表 */
    private updatePageList() {
        let data = this.getCurrentConfigData();
        this.pageList.numItems = 0;
        this.pageList.data = [data.values, data.values_remark];
        this.pageList.numItems = data.values.length;
    }

    private inputNameChanged(input: CS.FairyGUI.GTextInput, index: number) {
        let data = this.getCurrentConfigData();
        data.values[index] = input.text;
    }

    private inputRemarkChanged(input: CS.FairyGUI.GTextInput, index: number) {
        let data = this.getCurrentConfigData();
        data.values_remark[index] = input.text;
    }

    private onAddControllerClick() {
        let data = this.creatorControllerData("c" + this.keys.length);
        this.keys.push(data.name);

        this.datas[data.name] = data;
        this.updateCombox(data.name)
        this.updatePageList();
    }

    private onDelControllerClick() {
        let key = this.c_name.value;
        if (key == "") {
            return;
        }
        delete this.datas[key];
        this.keys.splice(this.keys.indexOf(key), 1);
        this.updateCombox(this.keys[0])
        this.updatePageList();
    }

    private onAddPageClick() {
        let data = this.getCurrentConfigData();
        data.values.push("");
        data.values_remark.push("");
        let selectedIndex = this.pageList.selectedIndex;
        this.updatePageList();
        this.pageList.selectedIndex = selectedIndex;
    }


    private onRemovePageClick() {
        let selectedIndex = this.pageList.selectedIndex;
        if (selectedIndex == -1) {
            return;
        }

        let data = this.getCurrentConfigData();
        data.values.splice(selectedIndex, 1);
        data.values_remark.splice(selectedIndex, 1);
        this.updatePageList();
        this.pageList.selectedIndex = selectedIndex;
    }

    private onMoveUpClick() {
        let selectedIndex = this.pageList.selectedIndex;
        if (selectedIndex == -1 || selectedIndex == 0) {
            return;
        }

        let data = this.getCurrentConfigData();
        let temp = data.values[selectedIndex];
        data.values[selectedIndex] = data.values[selectedIndex - 1];
        data.values[selectedIndex - 1] = temp;

        temp = data.values_remark[selectedIndex];
        data.values_remark[selectedIndex] = data.values_remark[selectedIndex - 1];
        data.values_remark[selectedIndex - 1] = temp;

        this.updatePageList();
        this.pageList.selectedIndex = selectedIndex - 1;

    }

    private onMoveDownClick() {
        let selectedIndex = this.pageList.selectedIndex;
        if (selectedIndex == -1 || selectedIndex == this.pageList.numItems - 1) {
            return;
        }

        let data = this.getCurrentConfigData();
        let temp = data.values[selectedIndex];
        data.values[selectedIndex] = data.values[selectedIndex + 1];
        data.values[selectedIndex + 1] = temp;

        temp = data.values_remark[selectedIndex];
        data.values_remark[selectedIndex] = data.values_remark[selectedIndex + 1];
        data.values_remark[selectedIndex + 1] = temp;

        selectedIndex = this.pageList.selectedIndex;
        this.updatePageList();
        this.pageList.selectedIndex = selectedIndex + 1;
    }

    private onInsertPageClick() {
        let selectedIndex = this.pageList.selectedIndex;
        if (selectedIndex == -1) {
            return;
        }

        let data = this.getCurrentConfigData();
        data.values.splice(selectedIndex, 0, "");
        data.values_remark.splice(selectedIndex, 0, "");
        this.updatePageList();
        this.pageList.selectedIndex = selectedIndex;
    }

    private onSaveClick() {
        let map = {};
        for (let index = 0; index < this.keys.length; index++) {
            map[this.keys[index]] = this.datas[this.keys[index]];
            
        }
        SG.config[Config.CUSTOMCONTROLLERNAME] = map;
        ToolMgr.saveConfig(SG.config_path);
        this.onCancelClick();
    }

    private onCancelClick() {
        let self = this;
        this.Hide();
        FairyGUI.Timers.inst.Add(0.05, 1, () => {
            UIWind.remove(self)
        })
    }
}

